package org.web2024.service.serviceimp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.web2024.dao.Course;
import org.web2024.dao.Student;
import org.web2024.dao.UserdetailsImp;
import org.web2024.mapper.StudentMapper;
import org.web2024.service.StudentService;

import java.util.*;

@Service
public class StudentServiceImp implements StudentService {
    @Autowired
    private StudentMapper mp;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Override
    public Map<String, Object> showSelectedCourse(String sno,String selCyear) {
        String currentterm=(String) redisTemplate.opsForHash().get("currentterm", "termname");
        if(!selCyear.equals(currentterm)){
            Map<String,Object> map=new HashMap<>();
            map.put("courseList",mp.showSelectedCourse(sno, selCyear));
            map.put("coin",null);
            return map;
        }
        Set<Object> keys=redisTemplate.opsForHash().keys("student:"+sno);
        keys.remove("coins");
        if(keys.isEmpty())
            return null;
        List<Course> courseList=new ArrayList<>();
        List<Integer>coin=new ArrayList<>();
        keys.forEach(key->{
            String keytostring=key.toString();
            courseList.add((Course) redisTemplate.opsForValue().get("course:"+keytostring));
            coin.add((Integer) redisTemplate.opsForHash().get("student:"+sno,keytostring));
        });
        Map<String,Object> map=new HashMap<>();
        map.put("courseList",courseList);
        map.put("coin",coin);
        return map;
    }

    @Override
    public List<Course> showAllCourse() {
        return mp.showAllCourse();
    }

    @Override
    public Student showStudentInfo(String sno){
        return mp.showStudentInfo(sno);
    }
    @Override
    public List<Course> showOptionalCourse(String typestr,String selCyear) {
        return mp.showOptionalCourse(typestr,selCyear);
    }
    @Override
    public boolean modifyStudentinfo(String sno,String s_email){
            return mp.modifyStudentinfo(sno,s_email);
    }
    @Override
    public HashMap<String,Object> searchCourse(String c_no){
        String s_no= ((UserdetailsImp) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUser().getUser_no();
        Object coin=redisTemplate.opsForHash().get("student:"+s_no,"coins");
        String courseno="course:"+c_no;
        Course course= (Course) redisTemplate.opsForValue().get(courseno);
        Object size =redisTemplate.opsForZSet().size("coursecoin:"+c_no);
        HashMap<String,Object> map=new HashMap<>();
        map.put("leftcoin",coin);
        map.put("selectcoursesize",size);
        map.put("course",course);
        return map;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean confirmCourse(String c_no,int coins){
        String s_no=((UserdetailsImp) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
        if(redisTemplate.opsForZSet().score("coursecoin:"+c_no,s_no)!=null)
        {
            return false;//已选则返回false
        }
        if(redisTemplate.opsForHash().get("student:"+s_no,"coins")==null)
            redisTemplate.opsForHash().put("student:"+s_no,"coins",100);
        long currentTimeMillis = System.currentTimeMillis();
        double score=currentTimeMillis/1000.0/1e6;
        redisTemplate.opsForZSet().add("coursecoin:"+c_no,s_no,coins);
        redisTemplate.opsForHash().put("student:"+s_no,c_no,coins+score);
        redisTemplate.opsForHash().increment("student:"+s_no,"coins",-coins);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deletecourse(String c_no) {
        String s_no=((UserdetailsImp) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
        Double coins = redisTemplate.opsForZSet().score("coursecoin:"+c_no,s_no);
        if(coins==null)
            return false;
        redisTemplate.opsForHash().increment("student:"+s_no,"coins",coins);
        redisTemplate.opsForZSet().remove("coursecoin:"+c_no,s_no);
        redisTemplate.opsForHash().delete("student:"+s_no,c_no);
        return true;
    }
}